﻿using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace EMall.Cache
{
    public class CacheManager : ICacheManager
    {
        public CacheKeyCollection<string> Keys { get; }
        private readonly IMemoryCache _memoryCache;
        public CacheManager(IMemoryCache memoryCache)
        {
            Keys = new CacheKeyCollection<string>();
            _memoryCache = memoryCache;
        }
        public async Task<TItem> TryGetValueAsync<TItem>(string key, Func<Task<TItem>> factory)
        {
            key = key.ToLower();
            if (!_memoryCache.TryGetValue(key, out TItem? value))
            {
                value = await factory.Invoke();
                var options = new MemoryCacheEntryOptions
                {
                    SlidingExpiration = TimeSpan.FromMinutes(5)  // 每次访问缓存时重置过期时间
                };
                _memoryCache.Set(key, value, options);
                Keys.TryAdd(key);
            }
            return value;
        }
        public async Task TryRefreshValueAsync<TItem>(string key, Func<Task<TItem>> factory)
        {
            key = key.ToLower();
            _memoryCache.Remove(key);
            var value = await factory.Invoke();
            var options = new MemoryCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromMinutes(5)  // 每次访问缓存时重置过期时间
            };
            _memoryCache.Set(key, value, options);
            Keys.TryAdd(key);
        }
    }
    public static class CacheManagerServiceCollectionExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddCacheManager(this IServiceCollection services)
        {
            services.AddMemoryCache();
            services.TryAdd(ServiceDescriptor.Singleton<ICacheManager, CacheManager>());
            return services;
        }
    }
}
